#coding:utf-8

import requests, os, time

from rgb import getXY, getXY_white
from imageconvert import image_convert_duibidu
from ldn_area import check_image
from ldn_area import image_convert_duibidu as image_convert_duibidu_ldn
import numpy as np


from PIL import Image
import numpy as np
from amg import main
import argparse

View_IP = "169.254.219.60"
Hexor_IP = "169.254.219.60"
Inference_IP = "169.254.80.196"
target_dof = [0, 0, 0, -1.9001, 2.2392, 0]

'''
运行服务器:192.168.2.83
用户名:iscas
密码:iscas
运行conda环境:minigptv
文件路径:/home/iscas/webapp/
'''

'''
don't move z and w axis
'''

'''
u and y control x axis
v and x control y axis 
'''

def download_file(url, save_path):
    try:
        # 发送 GET 请求下载文件
        with requests.get(url, stream=True) as response:
            # 检查请求是否成功
            if response.status_code == 200:
                # 打开文件并写入内容
                with open(save_path, 'wb') as file:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:  # 避免写入空的块
                            file.write(chunk)
                print(f"文件已成功下载到: {save_path}")
            else:
                print(f"下载失败，服务器响应状态码: {response.status_code}")
    except Exception as e:
        print(f"下载过程中发生错误: {e}")

# 截屏摄像头
def request_screenshot(image_type="huidu"):
    try:
        # 发送POST请求到服务器，通知进行截屏操作，并传递截图区域参数
        data = {"pos_x": 50, "pos_y": 100, "operator": "viewer"}
        server_url = f"http://{View_IP}:9052/screenshot"
        response = requests.post(server_url, json=data)

        # 检查响应状态码
        if response.status_code == 200:
            # 成功时，解析并打印返回的截图路径
            result = response.json()
            print(f"Screenshot taken successfully. Path: {result['screenshot_path']}")
            screenshot_path = result.get("screenshot_path").replace('\\', '/')
            screenshot_name = os.path.basename(screenshot_path)
            file_url = f"http://{View_IP}:9052/download/{screenshot_name}" 
            save_path = os.path.join(os.path.dirname(__file__), "samples", "laser", "rgb", "1206", screenshot_name)
            download_file(file_url, save_path)
            if image_type != "huidu":
                cor = getXY(save_path)
                print('='*50)
                print(f'red point coordinates:{cor[0]}')
                print(f'black point coordinates:{cor[1]}')
                print('='*50)
                return cor[0], cor[1]
            else:
                output_image_path = os.path.join(os.path.dirname(__file__), "samples", "laser", "huidu", "1206", screenshot_name)
                image_convert_duibidu(save_path, output_image_path)
                cor = getXY_white(output_image_path)
                print('*'*50)
                print(f'white point coordinates:{cor[0]}')
                print('*'*50)
                return cor[0], cor[1]
        else:
            # 响应出错时，打印错误信息
            print(f"Failed to take screenshot. Status Code: {response.status_code}")
            print(f"Error: {response.text}")
            return None, None

    except Exception as e:
        print(f"An error occurred: {e}")
        return None, None

# 截屏干涉图样        
def request_screenshot_interfere():
    try:
        # 发送POST请求到服务器，通知进行截屏操作，并传递截图区域参数
        data = {"pos_x": 50, "pos_y": 100, "operator": "interfere"}
        server_url = f"http://{Inference_IP}:9052/screenshot"
        response = requests.post(server_url, json=data)

        # 检查响应状态码
        if response.status_code == 200:
            # 成功时，解析并打印返回的截图路径
            result = response.json()
            print(f"Screenshot taken successfully. Path: {result['screenshot_path']}")
            screenshot_path = result.get("screenshot_path").replace('\\', '/')
            screenshot_name = os.path.basename(screenshot_path)
            file_url = f"http://{Inference_IP}:9052/download/{screenshot_name}" 

            # save_path = os.path.join(os.path.dirname(__file__), screenshot_name)
            save_path_rgb = os.path.join(os.path.dirname(__file__), "samples", "inference", "rgb", "1206", screenshot_name)
            download_file(file_url, save_path_rgb)
            save_path_huidu = os.path.join(os.path.dirname(__file__), "samples", "inference", "huidu", "1206", screenshot_name)
            print('='*50)
            return save_path_rgb, save_path_huidu, screenshot_name.split(".")[0]
        else:
            # 响应出错时，打印错误信息
            print(f"Failed to take screenshot. Status Code: {response.status_code}")
            print(f"Error: {response.text}")

    except Exception as e:
        print(f"An error occurred: {e}")

def generate_control_list(u_step):
    control_list = []
    DOFs = ['x', 'y', 'z', 'u', 'v', 'w']
    for i in range(6):
        dof = DOFs[i]
        step_size = abs(u_step[i])
        if step_size == 0:
            continue  # 如果步长为0，则不需要发送控制指令
        increase_or_decrease = f"{dof}_increase" if u_step[i] >= 0 else f"{dof}_decrease"
        # 设置步长
        control_list.append({
            "soft_name": f"{dof}_stepsize",
            "input": str(step_size),
            "click_type": "left",
            "click_num": 1,
            "time_sleep": 3,
            "press_enter": True,
        })
        # 执行增大或减小操作
        control_list.append({
            "soft_name": increase_or_decrease,
            "input": None,
            "click_type": "left",
            "click_num": 1,
            "time_sleep": 3,
            "press_enter": False,
        })
    return control_list

def train_model(current_red_center):
    u_step_x = [3,0,0,0,0,0]
    control_list = generate_control_list(u_step_x)
    remote_control_test(control_list)
    time.sleep(10)
    red_center, _ = request_screenshot()
    delta_y = red_center[1] - current_red_center[1]
    current_red_center = red_center
    print(delta_y)
    kx = delta_y//3
    print("------kx: ",kx)

    u_step_y = [0,3,0,0,0,0]
    control_list = generate_control_list(u_step_y)
    remote_control_test(control_list)
    time.sleep(10)
    red_center, _ = request_screenshot()
    delta_x = red_center[0] - current_red_center[0]
    current_red_center = red_center
    print(delta_x)
    ky = delta_x//3
    print("------ky: ",ky)

    u_step_u = [0,0,0,0.1,0,0]
    control_list = generate_control_list(u_step_u)
    remote_control_test(control_list)
    time.sleep(10)
    red_center, _ = request_screenshot()
    delta_x = red_center[0] - current_red_center[0]
    current_red_center = red_center
    print(delta_x)
    ku = delta_x//0.1
    print("------ku: ",ku)

    u_step_v = [0,0,0,0,0.1,0]
    control_list = generate_control_list(u_step_v)
    remote_control_test(control_list)
    time.sleep(10)
    red_center, _ = request_screenshot()
    delta_y = red_center[1] - current_red_center[1]
    current_red_center = red_center
    print(delta_y)
    kv = delta_y//0.1
    print("------kv: ",kv)

    return kx,ky,ku,kv

def is_converged(current_center, target_center, threshold=3):
    distance = np.linalg.norm(np.array(current_center) - np.array(target_center))
    print(f"Current distance to target: {distance}")
    return distance < threshold

# 远程控制调试        
def remote_control_test(control_list):
    try:
        # 发送POST请求到服务器，通知进行控制操作
        data = {
                "operator": "hexor",
                "control_list": control_list
            }
        server_url = f"http://{Hexor_IP}:9052/screenshot"
        response = requests.post(server_url, json=data)

        # 检查响应状态码
        if response.status_code == 200:
            # 成功时，解析并打印返回的信息
            result = response.json()
            print(f"======== {result['message']}")
        else:
            # 响应出错时，打印错误信息
            print(f"Failed to send control commands. Status Code: {response.status_code}")
            print(f"Error: {response.text}")

    except Exception as e:
        print(f"An error occurred: {e}")

# 激光斑点调节控制函数
def laser_adapter(initial_dof):
    # step 1:发送指令,从客户端A上截图摄像头拍摄的激光灯图样
    # step 2:调用计算激光灯和小孔坐标的脚本
    _, black_center = request_screenshot(image_type="RGB") 
    red_center, _ = request_screenshot(image_type="huidu")

    kx = -20
    ky = -20
    ku = -1000
    kv = 993

    kx,ky,ku,kv = train_model(red_center)
    delta_x = black_center[0] - red_center[0]
    delta_y = black_center[1] - red_center[1]

    print("delta_x, delta_y:  ", delta_x, delta_y)
    
    # 通过 u v 进行粗调
    delta_u = delta_x/ku
    delta_v = delta_y/kv

    control_list = [0,0,0,delta_u,delta_v,0]
    control_list = generate_control_list(control_list)
    print("------------control_list-------",control_list)
    remote_control_test(control_list)
    
    # 通过 x y 进行细调
    while True:
        red_center, _ = request_screenshot() 
        print("white, black:",red_center,black_center)
        if red_center == None or is_converged(red_center,black_center) == True:
            break
        delta_x = black_center[0] - red_center[0]
        delta_y = black_center[1] - red_center[1]
        delta_control_y = delta_x/ky
        delta_control_x = delta_y/kx
        control_list = [delta_control_x, delta_control_y,0,0,0,0]
        control_list = generate_control_list(control_list)
        print("------------control_list-------",control_list)
        remote_control_test(control_list)

def check_inference_image():
    input_image_path1, save_path_huidu, segment_dir_name = request_screenshot_interfere()
    # input_image_path1 = r"E:\桌面\实习工作期间资料\samples\3.jpg"
    # folder_path = r"E:/桌面/实习工作期间资料/222"  # 替换为包含待检测图片的文件夹路径
    folder_path = os.path.join(os.path.dirname(__file__), "samples", "inference", "segmentoutputs", "1206") 

    image_convert_duibidu(input_image_path1, save_path_huidu)

    # 设置你自己的命令行参数
    args = argparse.Namespace(
        input=save_path_huidu,  # 输入 grey image
        output=folder_path,  # 输出文件夹路径
        model_type="vit_h",  # 模型类型
        checkpoint="/home/iscas/webapp/ldn_weixing/segmentanything/sam_vit_h_4b8939.pth",  # SAM模型检查点路径
        device="cuda",  # 设备选择
        convert_to_rle=False,  # 是否保存为COCO RLE格式
        points_per_side=16,  # 自定义其他参数
        points_per_batch=4,
        pred_iou_thresh=0.5,
        stability_score_thresh=0.3,
        stability_score_offset=0.0,
        box_nms_thresh=0.2,
        crop_n_layers=1,
        crop_nms_thresh=0.3,
        crop_overlap_ratio=0.5,
        crop_n_points_downscale_factor=2,
        min_mask_region_area=100
    )
    # 调用导入的 main 函数
    main(args)

    is_complete = check_image(os.path.join(folder_path, segment_dir_name))

    print("is_complete =", is_complete)

# 获取 zenik 系数
def get_zenik_value():
    try:
        # 发送POST请求到服务器，通知进行截屏操作，并传递截图区域参数
        data = {"operator": "zenik"}
        server_url = f"http://{Inference_IP}:9052/screenshot"
        response = requests.post(server_url, json=data)

        # 检查响应状态码
        if response.status_code == 200:
            # 成功时，解析并打印返回的截图路径
            result = response.json()
            print(f"Zenik got successfully. value: {result['zenik']}")
            zenik = result.get("zenik")
            return zenik
        else:
            # 响应出错时，打印错误信息
            print(f"Failed to get zenik. Status Code: {response.status_code}")
            print(f"Error: {response.text}")
    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == "__main__":

    # laser_adapter(target_dof)    

    # red_center, _ = request_screenshot(image_type="huidu")

    # _, black_center = request_screenshot(image_type="RGB") 
    # print("black_center =", black_center)

    check_inference_image()
